﻿using System.Collections.Generic;
using UnityEngine;

namespace Core
{
    /// <summary>
    /// 移动代理，默认线性移动。后面改为抛物线运动，修改重力的方式更好
    /// </summary>
    public class MoveAgent
    {
        protected Bullet bullet;
        protected Vector3 position;
        protected Vector3 orientation;
        protected Vector3 moveDir;

        public ColliderResult MoveResult = default;
        public bool IsDisposed { get; private set; }

        public MoveAgent()
        {
            MoveResult.targets = new List<Unit>();
        }

        public void Attach(Bullet bullet)
        {
            this.bullet = bullet;
        }

        public void Start(Vector3 position, Vector3 orientation)
        {
            this.position = position;
            this.orientation = orientation;

            bullet.SetPosition(this.position);
            bullet.SetRotate(Quaternion.Euler(orientation));
            OnStart();
        }

        public BulletMoveStatus Update()
        {
            MoveResult.hit = false;
            return TryMove(CalculateNewPosition());
        }

        protected virtual void OnStart()
        {

        }

        protected virtual Vector3 CalculateNewPosition()
        {
            return position + orientation * bullet.config.moveSpeed * Time.deltaTime;
        }

        protected virtual BulletMoveStatus TryMove(Vector3 newPosition)
        {
            var moveStatus = TryCollide(position, newPosition);
            if (moveStatus == BulletMoveStatus.Stop)
                return moveStatus;

            bullet.SetRotate(Quaternion.Euler(newPosition - position));
            bullet.SetPosition(newPosition);
            position = newPosition;

            return moveStatus;
        }

        protected virtual BulletMoveStatus TryCollide(Vector3 oldPosition, Vector3 newPosition)
        {
            var colliders = Physics.OverlapSphere(newPosition, bullet.config.collideSize, bullet.config.layerMask);

            if (colliders.Length != 0)
            {
                MoveResult.targets.Clear();
                var unitComponent = World.GetComponent<UnitComponent>();
                foreach (var collider in colliders)
                {
                    if (unitComponent.TryGetUnit(collider.transform, out var unit))
                    {
                        if (unit == bullet.caster)
                            continue;

                        MoveResult.targets.Add(unit);
                    }
                }

                if (MoveResult.targets.Count > 0)
                {
                    MoveResult.hit = true;
                    return BulletMoveStatus.Stop;
                }
            }
            return BulletMoveStatus.Move;
        }
    }

}
